package lwf.web.struts.action.worksheet;

import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lwf.db.manager.worksheet.WorkSheetManager;
import lwf.web.struts.action.WorkSheetAction;
import net.lwf.common.constant.ICommonConstant;
import net.lwf.constant.IDalConstant;
import net.lwf.exception.ExceptionUtil;
import net.lwf.file.util.FileReader;
import net.lwf.hibernate.entity.User;
import net.lwf.hibernate.entity.lookup.Lookup;
import net.lwf.hibernate.entity.worksheet.WorkSheetInfo;
import net.lwf.hibernate.entity.worksheet.WsType;
import net.lwf.security.DesEncryptor;
import net.lwf.service.LookupService;
import net.lwf.web.servlet.pdf.PdfProcessingServlet;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;



public class WsInfoAction extends WorkSheetAction {
	
	public ActionForward home(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		WsInfoActionForm wsiaform = (WsInfoActionForm) form;
		this.setBaseData(wsiaform);
		//Get the value for the grade from the user object and set to the form
		if(wsiaform.getSelectedGrade() != null && wsiaform.getSelectedSubject() != null) {
			String grade = wsiaform.getSelectedGrade();
			String subject = wsiaform.getSelectedSubject();
			WorkSheetManager manager = new WorkSheetManager();
			Map<String, Map<WsType, List<WorkSheetInfo>>> topics = manager.getUniqueWorkSheetByGradeSubject(grade, subject);
			wsiaform.setAlluniquewsdata(topics);
			wsiaform.setAvailableWorkSheetCount(manager.getAvailableWorksheetCount(grade, subject));
			//wsiaform.setTotalGradeWorksheetCount(manager.getAvailableWorksheetCount(grade));

		}

		return mapping.findForward("home");

	} //home
	
	private void setBaseData(WsInfoActionForm wsiaform) {
		//wsiaform.setGrades(LookupFactory.getInstance().getData(IDalConstant.GRADES));
		wsiaform.setGrades(new LookupService().getData(IDalConstant.GRADES));
		List<Lookup> subjects = new ArrayList<Lookup>();
		Lookup lkp = new Lookup();
		lkp.setKey(" ");
		lkp.setValue(" -- Select subject --");
		subjects.add(lkp);
		//subjects.addAll(LookupFactory.getInstance().getData(IDalConstant.SUBJECTS));
		subjects.addAll(new LookupService().getData(IDalConstant.SUBJECTS));
		wsiaform.setSubjects(subjects);
	}
	
	public ActionForward print(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
	   	String[] baseInfo = this.getPrintFile(request);
    	String wsId = baseInfo[0];
    	String filepath = baseInfo[1];
    	//String baseFolder = LookupFactory.getInstance().getValue(IDalConstant.PDF, IDalConstant.PDF_BASE_FOLDER_KEY);
    	String baseFolder = new LookupService().getValue(IDalConstant.PDF, IDalConstant.PDF_BASE_FOLDER_KEY);
    	
    	long id = Long.parseLong(wsId);
    	User user = (User) getWebUser(request).getUser();

		//Verify whether the file is printed/accessed by the logged in user in the current day
		WorkSheetManager manager = new WorkSheetManager();
		boolean wsaccessed = manager.workSheetAccessed(user.getId(), this.formatWsAccessKey(filepath));
		
		if(!wsaccessed || (wsaccessed && !manager.workSheetHasRestrictions(id))) {
		    String contentType = getServlet().getServletContext().getMimeType(filepath);
	    	response.setContentType(contentType);
	        OutputStream out = response.getOutputStream();
	        byte[] pdfContent = FileReader.loadFile(baseFolder + filepath);
	        out.write(pdfContent, 0, pdfContent.length); //This should be same as out.write(b);
	        if (out != null) {
	            out.close();
	        }
	        //Log the entry
	        manager.logWorkSheetAccess(user.getId(), id, this.formatWsAccessKey(filepath));
		}
		else {
			return mapping.findForward("printerror");
		}
		
		return null;
	}
    
    private String[] getPrintFile(HttpServletRequest request) {
    	String[] data = new String[2];  //first element is wsId and second element is filepath
		String printKey = request.getParameter("key");

		if(printKey != null) {
			//decode the key first
			String decodedPrintKey = null;
			try {
				decodedPrintKey = URLDecoder.decode(printKey, ICommonConstant.CHARACTER_ENCODING);
			} catch (UnsupportedEncodingException useex) {
				ExceptionUtil.logAndThrowException(PdfProcessingServlet.class, useex);
			}
			decodedPrintKey = decodedPrintKey.replace(ICommonConstant.SPACE, ICommonConstant.PLUS);
			//decrypt key
//			String encryptionKey = LookupFactory.getInstance().getValue(IDalConstant.SECURITY, IDalConstant.DESEDE_ENCRYPTION_KEY);
//			String encryptionScheme = LookupFactory.getInstance().getValue(IDalConstant.SECURITY, IDalConstant.DESEDE_ENCRYPTION_SCHEME_KEY);
			LookupService service = new LookupService();
			String encryptionKey = service.getValue(IDalConstant.SECURITY, IDalConstant.DESEDE_ENCRYPTION_KEY);
			String encryptionScheme = service.getValue(IDalConstant.SECURITY, IDalConstant.DESEDE_ENCRYPTION_SCHEME_KEY);
			DesEncryptor encryptor = new DesEncryptor(encryptionScheme, encryptionKey);
			String decrypted = encryptor.decrypt(decodedPrintKey);
			StringTokenizer stk = new StringTokenizer(decrypted, ICommonConstant.PIPE);
			String wsId = stk.nextToken();
			String filepath = stk.nextToken();

			data[0] = wsId;
			data[1] = filepath;

		}
		else {
			//No print key
		}
		return data;
    }
		
		private String formatWsAccessKey(String source) {
			String formatted = "";
			formatted = new StringBuilder(source).reverse().toString();
			int pos = formatted.indexOf(ICommonConstant.FORWARD_SLASH);
			formatted = formatted.substring(pos+1);
			formatted =  new StringBuilder(formatted).reverse().toString();
			return formatted;
		}

}
